package com.fzrskj.cloud.free.core.filter;

import com.fzrskj.cloud.free.consts.AppCode;
import com.fzrskj.cloud.free.core.AppStatus;
import com.fzrskj.cloud.free.core.tool.*;
import com.fzrskj.cloud.free.core.utils.CloudContextUtils;
import com.fzrskj.cloud.free.core.utils.EncryptUtils;
import com.fzrskj.cloud.free.sys.utils.*;
import com.fzrskj.cloud.free.sys.vo.AgentAccountMessageVo;
import com.fzrskj.cloud.free.thridparty.pay.wechat.WechatPay;
import ms.core.consts.SysErr;
import ms.core.support.Session;
import ms.core.tool.StrTool;
import ms.core.tool.XmlCodeParser;
import net.sf.json.JSONArray;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * CoreFilter.
 *
 * @author zj.
 *         Created on 2018/8/13 0013.
 */
public class CoreFilter implements Filter {
    public CoreFilter() {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse)response;
        System.setProperty("user.timezone", "GMT +08");

        //安全设置
        resp.addHeader("X-Frame-Options", "SAMEORIGIN");
        resp.addHeader("X-XSS-Protection", "1; mode=block");
        resp.addHeader("X-Content-Type-Options", "nosniff");

        //设置debug
        AppStatus.setDebug(Boolean.valueOf(SystemConfig.getProper("debug")));

        //代理信息设置;
        AgentAccountMessageVo messageVo = new AgentAccountMessageVo();
        if (!AgentAccountUtils.setAgentInfo(req, messageVo)) {
            resp.setStatus(403);
            String ret = XmlCodeParser.formatResultTips(false, messageVo.getCode(), messageVo.getMessage());
            CResponseTool.doResponseText(resp, ret);
            return;
        }

        String sid = CCookieTool.getSessionId(req);
        Session session = CSessionTool.getSessionCloud(sid);
        if (null == session) {
            CSessionTool.newSessionCloud(sid);
            session = CSessionTool.getSessionCloud(sid);
        }

        //代理设置登录
        if (messageVo.getNewSession()) {
            session = new Session();
            session.setId(messageVo.getUserAccount().getId());
            session.setUID(messageVo.getUserAccount().getUserId());
            session.setUname(messageVo.getUserAccount().getUserName());
            //set user account email
            session.setData(messageVo.getUserAccount().toJsonString());
            session.setUtype(1);
            //TODO to fill user functions
            session.setFuncs("");
            CSessionTool.setLoginSessionCloud(sid, session);
        }
        CloudContextUtils.setSession(session);

        String uri = req.getRequestURI();

        //模板跳转.
        IndexStaticUtils.toTemplateIndex(req, resp, uri);

        //页面代理翻译处理.
        if (AgentRequestUtils.agentRequest(req, resp, uri)) {
            return;
        }

        //动态JS模板静态华
        if (HtmlTplUtils.doCache(req, resp, uri)) {
            return;
        }


        Integer apiType = 0;
        if (!uri.startsWith("/sys.do")) {
            apiType = 1;
        }
        String fnName = req.getParameter("fn");

        if (!StrTool.isBlankStr(fnName)) {
            //Api api = XmlFunParser.getApi(apiType, fnName);
            CApi api = CXmlFunParser.getApi(apiType, fnName);
            //需要权限校验的接口
            if (null != api && !StrTool.isBlankStr(api.getFunctionCode())) {
                JSONArray array = CJsonTool.getJsonArray(session.getFuncs());
                String obj = String.format("{\"id\":\"%s\"}", api.getFunctionCode());
                if (!CJsonTool.objInJsonArray(array, obj)) {
                    String ret = XmlCodeParser.formatResultTips(false, SysErr.USER_NO_RIGHT);
                    CResponseTool.doResponseText(resp, ret);
                    return;
                }
            }
            //需要登录检查的接口
            if (null != api && !StrTool.isBlankStr(api.getCloudLogin()) && "Y".equals(api.getCloudLogin())) {
                int uid = CSessionTool.getUidCloud(sid);
                if (uid < 1) {
                    String ret = XmlCodeParser.formatResultTips(false, SysErr.USER_NOT_LOGIN);
                    CResponseTool.doResponseText(resp, ret);
                    return;
                }
            }
            //需要微服务检权的接口
            if (null != api && !StrTool.isBlankStr(api.getMiniServer()) && "Y".equals(api.getMiniServer())) {
                if (MiniServerApiCheckUtils.check(req)) {
                    String ret = XmlCodeParser.formatResultTips(false, AppCode.MINI_SERVER_API_CHECK_ERROR);
                    CResponseTool.doResponseText(resp, ret);
                    return;
                }
            }
        }

        //设置前端公钥响应.
        EncryptUtils.makePublic(resp);

        //特殊处理
        String sessionKey = EncryptUtils.getSession(req);
        if (null != sessionKey) {
            CloudContextUtils.setSK(sessionKey);
        }

        //将request存入会话，方便session处理
        CloudContextUtils.setHttpServletRequest(req);

        //设置请求参数
        CloudContextUtils.setP(req.getParameter("p"));

        //设置微信扫码支付
        WechatPay.init();

        chain.doFilter(request, response);

        //安全设置
        Cookie[] cookies = ((HttpServletRequest) request).getCookies();
        if(cookies!=null){
            for(Cookie cookie : cookies){
                String value = cookie.getValue();
                StringBuilder builder = new StringBuilder();
                builder.append(cookie.getName() + "=" + value + "; ");
                builder.append("Secure; ");
                builder.append("HttpOnly; ");
                Calendar cal = Calendar.getInstance();
                cal.add(Calendar.HOUR, 1);
                Date date = cal.getTime();
                Locale locale = Locale.CHINA;
                SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss",locale);
                builder.append("Expires=" + sdf.format(date));
                ((HttpServletResponse) response).setHeader("Set-Cookie", builder.toString());
            }
        }
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
    }
}
